/**
  ETFRoot project, Anyang Normal University && IMP-CAS

  \class ETFPXISection
  \brief class for holding a section (i.e. an event) for PXI daq
  \author SUN Yazhou, asia.rabbit@163.com
  \since 2021-09-27
  \date 2021-09-28 last modified
  \attention
  changelog
  <table>
  <tr>  <th>Date        <th>Author      <th>Description                    </tr>
  <tr>  <td>2021-09-27   <td>Asia Sun    <td>file created                   </tr>
  </table>

  \copyright Copyright (c) 2021 Anyang Normal U. && IMP-CAS with LGPLv3 LICENSE
*/

#include <TClonesArray.h>
#include "ETFPXISection.h"
#include "ETFPXIFragment.h"
#include "ETFRawChannel.h"
#include "ETFMsg.h"

ClassImp(ETFPXISection);

ETFPXISection::ETFPXISection() : TNamed("PXISection", "ETFPXISection")
  ,fSection_len(0), fFragments(new TClonesArray("ETFPXIFragment"))
  ,fHPTDCChannels(new TClonesArray("ETFHPTDCChannel"))
  ,fAmplitudeChannels(new TClonesArray("ETFAmplitudeChannel"))
{}

ETFPXISection::ETFPXISection(const ETFPXISection &sec) : TNamed(sec)
  ,fSectionHead(sec.fSectionHead), fSection_len(sec.fSection_len)
  ,fFragments(new TClonesArray(*sec.fFragments))
  ,fHPTDCChannels(new TClonesArray(*sec.fHPTDCChannels))
  ,fAmplitudeChannels(new TClonesArray(*sec.fAmplitudeChannels))
{}

ETFPXISection::~ETFPXISection(){
  fFragments->Delete(); delete fFragments;
  fHPTDCChannels->Delete(); delete fHPTDCChannels;
  fAmplitudeChannels->Delete(); delete fAmplitudeChannels;
} // end the destructor

void ETFPXISection::Reset(){
  fFragments->Clear();
  fHPTDCChannels->Clear();
  fAmplitudeChannels->Clear();
  fSection_len = 0;
  fSectionHead.initialize();
} // end member function Reset

TClonesArray *ETFPXISection::GetFragments() const{
  if(!fFragments) ETFMsg::Error("ETFPXISection", "GetFragments: required pointer is null");
  return fFragments;
} // end member function GetFragments

TClonesArray *ETFPXISection::GetHPTDCChannels() const{
  if(!fHPTDCChannels)
    ETFMsg::Error("ETFPXISection", "GetHPTDCChannels: required pointer is null");
  return fHPTDCChannels;
} // end the member function GetHPTDCChannels

TClonesArray *ETFPXISection::GetAmplitudeChannels() const{
  if(!fAmplitudeChannels)
    ETFMsg::Error("ETFPXISection", "GetAmplitudeChannels: required pointer is null");
  return fAmplitudeChannels;
} // end the member function GetAmplitudeChannels

// bunchid of the first fragment
unsigned ETFPXISection::GetBunchID() const{
  if(fFragments->GetEntries())
    return dynamic_cast<ETFPXIFragment *>(fFragments->At(0))->GetBunchID();
  return 0;
} // end member function GetBunchI

void ETFPXISection::PrintBunchID() const{
  if(!fSection_len){
    ETFMsg::Info("ETFPXISection", "PrintBunchID: Section length is 0. Empty section");
    return;
  } //  end if
  fSectionHead.print();
  if(!fFragments){
    ETFMsg::Info("ETFPXISection", "PrintBunchID: fFragments is nullptr");
    return;
  } //  end if

  TIter next(fFragments);
  ETFPXIFragment *frag;
  while((frag = dynamic_cast<ETFPXIFragment *>(next()))) frag->PrintBunchID();
} // end member function PrintBunchID

void ETFPXISection::PrintEventID() const{
  if(!fSection_len){
    ETFMsg::Info("ETFPXISection", "PrintEventID: Section length is 0. Empty section.");
    return;
  } //  end if
  fSectionHead.print();
  if(!fFragments){
    ETFMsg::Warn("ETFPXISection", "PrintEventID: fFragments is nullptr.");
    return;
  } //  end if

  TIter next(fFragments);
  ETFPXIFragment *frag;
  while((frag = dynamic_cast<ETFPXIFragment *>(next()))) frag->PrintEventID();
} // end member function PrintEventID

void ETFPXISection::Print() const{
  if(!fSection_len){
    ETFMsg::Info("ETFPXISection", "PrintBunchID: Section length is 0. Empty section.");
    return;
  } //  end if
  fSectionHead.print();
  if(!fFragments){
    ETFMsg::Warn("ETFPXISection", "Print: fFragments is nullptr.");
    return;
  } //  end if

  TIter next(fFragments);
  ETFPXIFragment *frag;
  while((frag = dynamic_cast<ETFPXIFragment *>(next()))) frag->Print();

  ETFRawChannel *ch;
  TIter next1(fHPTDCChannels), next2(fAmplitudeChannels);
  while((ch = dynamic_cast<ETFRawChannel *>(next1()))) ch->Print();
  while((ch = dynamic_cast<ETFRawChannel *>(next2()))) ch->Print();

  cout << "tch_num: " << fHPTDCChannels->GetEntries();
  cout << "\tach_num: " << fAmplitudeChannels->GetEntries() << endl;
  cout << "============== END SECTION " << GetEventIndex() << " ==============" << endl;
} // end member function Print
